<?php

declare(strict_types=1);

namespace app\sys\controller;

use app\sys\service\fileService;
use app\sys\service\SystemMenuService;
use think\admin\Controller;
use think\admin\Exception;
use think\admin\model\SysFile;
use think\admin\model\SysFileGroup;
use think\admin\Storage;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 文件接口
 * Class File
 * @package app\sys\controller
 */
class File extends Controller
{
    /**
     * 文件列表
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function list()
    {
        $query = SysFile::mQuery();
        $query->where(['is_deleted' => 0]);
        // 数据列表搜索过滤
        $query->equal('status')->dateBetween('create_time');
        $query->like('name,code');
        $query->dataScope('created_by');
        $lists = $query->order('id DESC')->page(false, false);
        $this->success('数据获取成功', $lists['list']);
    }

    /**
     * 文件上传分页列表
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function page()
    {
        $query = SysFile::mQuery();
        $query->where(['is_deleted' => 0]);
        // 数据列表搜索过滤
        $query->equal('status')->dateBetween('create_time');
        $query->like('name,code');
        $query->dataScope('created_by');
        $lists = $query->order('id DESC')->page();
        $this->success('数据获取成功', $lists['list']);
    }

    /**
     * 文件流下载图片
     * @auth true
     * @return void
     */
    public function download()
    {
        $id = $this->request->param('id');
        $file = SysFile::mk()->where(['is_deleted' => 0, 'status' => 0])->where(['id' => $id])->findOrEmpty();
        /**
         * blob返回浏览器下载，其他导出文件功能可以复用此代码
         */
        header("Content-Type: application/zip");
        header("Content-Transfer-Encoding: Binary");
        header("Content-Length: " . filesize($file['storagePath']));
        header("Content-Disposition: attachment; filename=\"" . basename($file['storagePath']) . "\"");
        readfile($file['storagePath']);
    }

    /**
     * 获取文件详情
     * @auth true
     * @return void
     */
    public function detail()
    {
        $this->success('获取成功！', SysFile::detail($this->request->param('id')));
    }

    /**
     * 删除文件及数据表文件
     * @auth true
     * @return array|void
     * @throws Exception
     */
    public function delete()
    {
        if (empty($id = $this->request->param('id'))) return [];
        $fileIds = explode(',', $id);
        foreach ($fileIds as $v) {
            $f = SysFile::mk()->where(['id' => $v])->findOrEmpty();
            if (!$f->isEmpty()) {
                if ($f['engine'] !== 'local') {
                    $safeMode = fileService::getSafe();
                    Storage::instance($f['storage'])->del($f['objName'], $safeMode);
                } else {
                    @unlink($f['objName']);
                }
            }
        }
        if (SysFile::mk()->whereIn('id', $fileIds)->delete()) {
            $this->success('成功删除');
        } else {
            $this->error('删除失败');
        }
    }

    /**
     * 移动文件
     * @auth true
     * @return void
     */
    public function move()
    {
        $data = $this->_vali([
            'group_id.require' => '新的分组必须选择！',
            'id.require' => 'ID不能为空！',
        ]);
        $ids = explode(',', $data['id']);
        if (SysFile::mk()->whereIn('id', $ids)->update(['group_id' => $data['group_id']])) {
            $this->success('文件移动成功！');
        } else {
            $this->error('文件移动失败！');
        }
    }

    /**
     * 文件选择器
     * @login true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function fileSelector()
    {
        $query = SysFile::mQuery();
        $query->where(['is_deleted' => 0]);
        $files = $query->equal('group_id,status')
            ->like('name')
            ->order('id desc')
            ->field('id,name,storage_path,suffix,size_info')
            ->page(false,false);
        sysoplog('文件管理', '文件选择器获取成功');
        $this->success('数据获取成功', $files['list']);
    }

    /**
     * 文件组树选择器
     * @login true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function groupTreeSelector()
    {
        $groups = SysFileGroup::mk()
            ->where(['is_deleted' => 0, 'status' => 0])
            ->order('id asc')
            ->field('*,parent_id as parentId')
            ->select()
            ->toArray();
        if($groups){
            foreach($groups as &$v){
                $v['id'] = $v['id'].'';
            }
        }
        $lists = SystemMenuService::instance()->toTree($groups);
        sysoplog('文件组管理', '文件组树选择器获取成功');
        $this->success('数据获取成功', $lists);
    }

    /**
     * 文件移动分组
     * @login true
     * @return void
     */
    public function fileSelectorGroupMovie()
    {
        SysFile::mForm();
    }

    /**
     * 新增分组
     * @login true
     * @return void
     */
    public function fileSelectorGroupAdd()
    {
        SysFileGroup::mForm();
    }

    /**
     * 文件选择器里的删除文件
     * @login true
     * @return array|void
     * @throws Exception
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function fileSelectorDelete()
    {
        if (empty($this->request->request('id'))) return [];
        $id = $this->request->request('id');
        $ids = explode(',', $id);
        foreach ($ids as $v) {
            $f = SysFile::mk()->where(['id' => $v])->find();
            $name = $f['objName'];
            $safeMode = fileService::getSafe();
            Storage::instance($f['storage'])->del($name, $safeMode);
        }
        if (SysFile::mk()->whereIn('id', $ids)->delete()) {
            $this->success('成功删除');
        } else {
            $this->error('删除失败');
        }
    }
}